package com.ccteam.fluidmusic.ui.artist

import androidx.lifecycle.*
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.map
import com.ccteam.fluidmusic.fluidmusic.common.MusicServiceConnectionFlow
import com.ccteam.fluidmusic.fluidmusic.common.utils.MediaIDHelper
import com.ccteam.fluidmusic.utils.cancelIfActive
import com.ccteam.shared.core.UserCore
import com.ccteam.shared.domain.artist.ArtistDetailMusicUseCase
import com.ccteam.shared.result.music.DefaultMusicItem
import com.ccteam.shared.utils.getPlaybackStatus
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/2/20
 *
 * 歌手详情页 歌曲列表信息分页 ViewModel
 * 用于加载显示歌手歌曲列表内容
 * 此处将分页库转换为 liveData 保证其能够进行内容的更改
 */
@HiltViewModel
class ArtistDetailMusicViewModel @Inject constructor(
    private val userCore: UserCore,
    private val mediaIDHelper: MediaIDHelper,
    private val musicServiceConnectionFlow: MusicServiceConnectionFlow,
    artistDetailMusicUseCase: ArtistDetailMusicUseCase,
    private val savedStateHandle: SavedStateHandle
): ViewModel() {

    val parentId = MutableLiveData(mediaIDHelper.createMediaId(
        MediaIDHelper.ONLINE_MEDIA_ARTIST,savedStateHandle["artistId"]
    ))

    private val _artistMusicLiveData: MutableLiveData<PagingData<DefaultMusicItem>> =
        artistDetailMusicUseCase(Pair(parentId.value,savedStateHandle["artistId"]))
            .cachedIn(viewModelScope).asLiveData().let {
                it as MutableLiveData<PagingData<DefaultMusicItem>>
            }

    val artistMusicLiveData: LiveData<PagingData<DefaultMusicItem>> get() = _artistMusicLiveData

    var isLogin: Boolean = false
    private set

    private var metadataChangedJob: Job? = null
    private var loginCheckJob: Job? = null

    init {

        metadataChangedJob = viewModelScope.launch {
            musicServiceConnectionFlow.nowPlaying.collectLatest {
                refreshNowPlaying()
            }
        }
        loginCheckJob = viewModelScope.launch {
            userCore.isLogin.collectLatest {
                isLogin = it
            }
        }
    }

    fun refreshNowPlaying(){
        val artistMusicList = artistMusicLiveData.value ?: return

        artistMusicList.map { item ->
            item.copy(playbackRes = musicServiceConnectionFlow.nowPlaying.value.getPlaybackStatus(item.mediaId))
        }.let {
            _artistMusicLiveData.value = (it)
        }
    }

    override fun onCleared() {
        super.onCleared()

        metadataChangedJob.cancelIfActive()
    }

}